﻿using Microsoft.CSharp.Activities;
using System;
using System.Activities;
using System.Activities.Statements;
using System.Activities.Validation;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WFExtended.Activities;
using WFExtended.Framework.Constraints;
using WFExtended.Framework.ServiceModel;

namespace WFExtended.Twitter.Activities
{
    /// <summary>
    /// Base class for a Twitter Operation Invoker
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class TwitterOperationInvoker<T> : WcfOperationInvoker<T>, ITwitterOperationActivity
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TwitterOperationInvoker{T}"/> class.
        /// </summary>
        /// <param name="operationName">Name of the operation.</param>
        public TwitterOperationInvoker(string operationName)
            : base(operationName, GetDefaultConstraints())
        {
            Proxy = new System.Activities.InArgument<Framework.ServiceModel.AWcfProxy>(new CSharpValue<AWcfProxy>("twitterProxy"));

            Variable<bool> enableRateLimitAutoRetry = new Variable<bool>("enableRateLimitAutoRetry", (c)=>c.GetExtension<TwitterExtension>().EnableRateLimitAutoRetry);
            Variable<TimeSpan> rateLimitAutoRetryDelay = new Variable<TimeSpan>("rateLimitAutoRetryDelay", (c) => c.GetExtension<TwitterExtension>().RateLimitAutoRetryDelay);

            _invokercatches.Add(new Catch<RateLimitException>()
            {
                Action = new ActivityAction<RateLimitException>()
                {
                    Handler = new Sequence()
                    {
                        Variables = {enableRateLimitAutoRetry, rateLimitAutoRetryDelay},
                        Activities = 
                        {
                            new If(enableRateLimitAutoRetry)
                            {
                                Then = new Sequence()
                                {
                                    Activities = 
                                    {
                                        new Delay() { Duration = rateLimitAutoRetryDelay }
                                    }
                                },
                                Else = new Rethrow()
                            },
                        }
                    }                   

                }
            });
        }

        private static Constraint[] GetDefaultConstraints()
        {
            return new Constraint[]
            {
                 new BeInsideConstraint<TwitterOperationInvoker<T>>(false, "Proxy", typeof(TwitterProxy)).GetConstraint()
            };
        }

        protected override Constraint[] GetCacheConstraints()
        {
            return new Constraint[] { };
        }

        /// <summary>
        /// Get or Set the WCF Proxy
        /// </summary>
        [Browsable(false)]
        public override InArgument<AWcfProxy> Proxy { get; set; }

        /// <summary>
        /// Get or Set the Operation Name
        /// </summary>
        [Browsable(false)]
        public override string OperationName { get; set; }

        /// <summary>
        /// Get or Set the Parameter of the operation Method
        /// </summary>
        [Browsable(false)]
        public override IDictionary<string, InArgument> Parameters { get; set; }
    }
}
